#!/bin/sh

###########################################################################
# Install Script - Start/Stop Script for Domino on xLinux/zLinux/AIX      #
# Version 3.7.0 09.01.2022                                                #
#                                                                         #
# (C) Copyright Daniel Nashed/NashCom 2005-2022                           #
# Feedback domino_unix@nashcom.de                                         #
#                                                                         #
# Licensed under the Apache License, Version 2.0 (the "License");         #
# you may not use this file except in compliance with the License.        #
# You may obtain a copy of the License at                                 #
#                                                                         #
#      http://www.apache.org/licenses/LICENSE-2.0                         #
#                                                                         #
# Unless required by applicable law or agreed to in writing, software     #
# distributed under the License is distributed on an "AS IS" BASIS,       #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.#
# See the License for the specific language governing permissions and     #
# limitations under the License.                                          #
###########################################################################

SCRIPT_NAME=$0
PARAM1=$1
SCRIPT_REAL=`realpath $0`
SCRIPT_DIR=`dirname $SCRIPT_REAL`

DOMINO_INSTALL_CONFIG_FILE=$SCRIPT_DIR/sysconfig/rc_domino_config
DOMINO_INSTALL_CONFIG_TARGET=/etc/sysconfig/rc_domino_config

DOMINO_DOCKER_SCRIPT=domino_docker_entrypoint.sh
DONT_TOUCH_THIS_NASHCOM_PATH=/opt/nashcom/startscript
DONT_TOUCH_THIS_STANDARD_USER=notes

DOMINO_SCRIPT_VERSION=3.6.2

# if you really really need to, change this and all files will be patched

if [ -z "$DOMINO_START_SCRIPT_DIR" ]; then
  DOMINO_START_SCRIPT_DIR=/opt/nashcom/startscript
fi

if [ -z "$DOMINO_USER" ]; then
  DOMINO_USER=notes
fi

if [ -z "$DOMINO_GROUP" ]; then
  DOMINO_GROUP=notes
fi

ROOT_USER=root
ROOT_GROUP=root

if [ -z "$DOMINO_DATA_PATH" ]; then
  DOMINO_DATA_PATH=/local/notesdata
fi

DOMINO_SCRIPT_BIN=/usr/bin/domino

#DOMINO_DEBUG_MODE="yes"

START_SCRIPT_DIR=`dirname $0`

if [ "$START_SCRIPT_DIR" = "/" ]; then
  START_SCRIPT_DIR=""
fi

if [ ! $EUID = "0" ]; then
  echo "Terminating installation - Please run as root user!"
  exit 1
fi

# first check standard location for existing config
if [ -r "$DOMINO_INSTALL_CONFIG_TARGET" ]; then
  . $DOMINO_INSTALL_CONFIG_TARGET
else

  # use fresh config (might be still customized)
  if [ -r "$DOMINO_INSTALL_CONFIG_FILE" ]; then
    . $DOMINO_INSTALL_CONFIG_FILE
  else
    echo "Terminating installation - cannot read config file! [$DOMINO_INSTALL_CONFIG_FILE]"
    exit 1
  fi
fi

INIT_PATH=/etc/init.d

# Determine architecture and platform
if [ `uname` = AIX ]; then
  LARCH=ibmpow
  PLATFORM_NAME=AIX
  INIT_PATH=/etc/rc.d
  ROOT_GROUP=system
elif [ `uname` = Linux ]; then
  LARCH=linux
  UNAME=`uname -m`
  if [ $UNAME = s390 ]; then
    PLATFORM_NAME=zLinux
  elif [ $UNAME = s390x ]; then
    PLATFORM_NAME=zLinux
  else
    PLATFORM_NAME=xLinux
  fi

  # Query linux distribution
  if [ ${LARCH} = "linux" ]; then
    if [ -e /etc/SuSE-release ]; then
      LINUX_DISTRIBUTION=suse
    elif [ -e /etc/redhat-release ]; then
      LINUX_DISTRIBUTION=redhat
    else
      LINUX_DISTRIBUTION=unknown
    fi
  fi
fi


header()
{
  echo
  echo "$@"
  echo
}

DebugText()
{
  if [ "$DOMINO_DEBUG_MODE" = "yes" ]; then

    if [ -z "$DOMINO_DEBUG_FILE" ]; then
      echo "Debug: $@"
    else
      echo "Debug: $@" >> $DOMINO_DEBUG_FILE 
    fi
  fi 

  return 0
}


create_link()
{
  if [ -z "$1" ]; then
    return 0
  fi 

  if [ -z "$2" ]; then
    return 0
  fi

  if [ -e "$2" ]; then
    echo "link already exists [$2]"
    return 0
  fi

  if [ ! -r "$1" ]; then
    return 0
  fi

  ln -s "$1" "$2"
}

check_file_busy()
{
  if [ ! -e "$1" ]; then
    return 0
  fi

  local TARGET_REAL_BIN=`readlink -f $1`
  local FOUND_TARGETS=`lsof "$TARGET_REAL_BIN" 2>/dev/null | grep "$TARGET_REAL_BIN"`

  if [ -n "$FOUND_TARGETS" ]; then
    return 1
  else
    return 0
  fi
}

nsh_cmp()
{
  if [ -z "$1" ]; then
    return 1
  fi

  if [ -z "$2" ]; then
    return 1
  fi

  if [ ! -e "$1" ]; then
    return 1
  fi

  if [ ! -e "$2" ]; then
    return 1
  fi

  if [ -x /usr/bin/cmp ]; then
    cmp -s "$1" "$2"
    return $?
  fi

  HASH1=`sha256sum "$1" | cut -d" " -f1`
  HASH2=`sha256sum "$2" | cut -d" " -f1`

  if [ "$HASH1" = "$HASH2" ]; then
    return 0
  fi

  return 1
}

install_file()
{
  SOURCE_FILE=$1
  TARGET_FILE=$2
  OWNER=$3
  GROUP=$4
  PERMS=$5

  if [ ! -r "$SOURCE_FILE" ]; then
    echo "[$SOURCE_FILE] Can not read source file"
    return 1
  fi

  if [ -e "$TARGET_FILE" ]; then

    nsh_cmp "$SOURCE_FILE" "$TARGET_FILE"
    if [ $? -eq 0 ]; then
      echo "[$TARGET_FILE] File did not change -- No update needed"
      return 0
    fi

    if [ ! -w "$TARGET_FILE" ]; then
      echo "[$TARGET_FILE] Can not update binary -- No write permissions"
      return 1
    fi

    check_file_busy "$TARGET_FILE"

    if [ $? -eq 1 ]; then
      echo "[$TARGET_FILE] Error - Can not update file -- Binary in use"
      return 1
    fi
  fi
  
  cp -f "$SOURCE_FILE" "$TARGET_FILE"
 
  if [ ! -z "$OWNER" ]; then
    chown $OWNER:$GROUP "$TARGET_FILE"
  fi

  if [ ! -z "$PERMS" ]; then
    chmod "$PERMS" "$TARGET_FILE"
  fi

  echo "[$TARGET_FILE] installed"

  return 2
}

install_file_noupdate()
{
  SOURCE_FILE=$1
  TARGET_FILE=$2
	
  if [ -e "$TARGET_FILE" ]; then
    echo "[$TARGET_FILE] Skipping file -- Not overwriting"  
    return 0
  fi
 
  install_file "$1" "$2" "$3" "$4" "$5" 
}

patch_install_dir()
{
  if [ ! -e "$1" ]; then
    echo "FILE DOES NOT EXIST: [$1]"
    return 0;
  fi

  if [ "$DONT_TOUCH_THIS_NASHCOM_PATH" = "$DOMINO_START_SCRIPT_DIR" ]; then
    return 0;
  fi

  sed -i "s~${DONT_TOUCH_THIS_NASHCOM_PATH}~${DOMINO_START_SCRIPT_DIR}~g" "$1"
}

patch_user_name()
{
  if [ ! -e "$1" ]; then
    echo "FILE DOES NOT EXIST: [$1]"
    return 0;
  fi

  if [ "$DONT_TOUCH_THIS_STANDARD_USER" = "$DOMINO_USER" ]; then
    return 0;
  fi

  sed -i "s~${DONT_TOUCH_THIS_STANDARD_USER}~${DOMINO_USER}~g" "$1"
}

copy_one_touch_templates()
{
  local TARGET_DIR=$DOMINO_START_SCRIPT_DIR/OneTouchSetup
  local SOURCE_DIR=$SCRIPT_DIR/OneTouchSetup
  mkdir -p -m 755 $TARGET_DIR
  cp -f $SOURCE_DIR/* $TARGET_DIR
  chown -R "$DOMINO_USER":"$DOMINO_GROUP" $TARGET_DIR
  chmod -R 644 $TARGET_DIR/*
  return 0
}

# rc script files install

header "Installing StartScript & Config"

if [ ! -e "$DOMINO_START_SCRIPT_DIR" ]; then
  mkdir -p -m 755 "$DOMINO_START_SCRIPT_DIR"
  # Depending on the umask the directory might have still the wrong permissions
  chmod 755 /opt/nashcom
fi

DebugText "DOMINO_USER: [$DOMINO_USER]" 
DOMINO_USER_GROUPID=`id -g "$DOMINO_USER" 2>/dev/null;`
DebugText "DOMINO_USER_GROUPID: [$DOMINO_USER_GROUPID]"
DebugText "START_SCRIPT_DIR: [$START_SCRIPT_DIR]"

if [ -z "$DOMINO_USER_GROUPID" ]; then
  echo "Terminating installation - User Linux '$DOMINO_USER' does not exist"
  exit 1
fi

if [ ! -e "$DOMINO_DATA_PATH" ]; then
  echo "Terminating installation - Domino data directory directory '$DOMINO_DATA_PATH' does not exist"
  exit 1
fi

# domino script is now /usr/bin. convert link when needed

if [ -L "$DOMINO_SCRIPT_BIN" ]; then
  echo "Replacing symbolic link [$DOMINO_SCRIPT_BIN] with script file"
  rm -f "$DOMINO_SCRIPT_BIN"

  # also remove old init.d name and replace with link further down in logic
  if [ -e "$INIT_PATH/$DOMINO_RC_NAME" ]; then
    rm -f "$INIT_PATH/$DOMINO_RC_NAME"
  fi

fi

install_file "$START_SCRIPT_DIR/rc_domino" "$DOMINO_SCRIPT_BIN" $ROOT_USER $ROOT_GROUP 755

install_file "$START_SCRIPT_DIR/rc_domino_script" "$DOMINO_START_SCRIPT_DIR/rc_domino_script" $ROOT_USER $ROOT_GROUP 755
install_file "$START_SCRIPT_DIR/rc_domino_readme.txt" "$DOMINO_START_SCRIPT_DIR/rc_domino_readme.txt" "$DOMINO_USER" "$DOMINO_GROUP" 644

install_file "$START_SCRIPT_DIR/nshinfo.sh" "$DOMINO_START_SCRIPT_DIR/nshinfo.sh" $ROOT_USER $ROOT_GROUP 755
install_file "$START_SCRIPT_DIR/DominoOneTouchSetup.sh" "$DOMINO_START_SCRIPT_DIR/DominoOneTouchSetup.sh" $ROOT_USER $ROOT_GROUP 755
install_file "$START_SCRIPT_DIR/nshcfg.sh" "$DOMINO_START_SCRIPT_DIR/nshcfg.sh" $ROOT_USER $ROOT_GROUP 755
install_file "$START_SCRIPT_DIR/domino.cfg" "$DOMINO_START_SCRIPT_DIR/domino-example.cfg" $ROOT_USER $ROOT_GROUP 755

START_SCRIPT_CONFIG_VER=$DOMINO_START_SCRIPT_DIR/rc_domino_config_$DOMINO_SCRIPT_VERSION.txt
START_SCRIPT_CONFIG_LATEST=$DOMINO_START_SCRIPT_DIR/rc_domino_config_latest.txt

install_file $DOMINO_INSTALL_CONFIG_FILE $START_SCRIPT_CONFIG_VER "$DOMINO_USER" "$DOMINO_GROUP" 644

if [ -e "$START_SCRIPT_CONFIG_LATEST" ]; then
  rm -f "$START_SCRIPT_CONFIG_LATEST"
fi

create_link $START_SCRIPT_CONFIG_VER $START_SCRIPT_CONFIG_LATEST

# create /etc/sysconfig if not present
if [ ! -e "/etc/sysconfig" ]; then
  mkdir -m 755 /etc/sysconfig
fi

if [ "$PARAM1" = "upd" ]; then
  install_file "$DOMINO_INSTALL_CONFIG_FILE" "$DOMINO_INSTALL_CONFIG_TARGET" "$DOMINO_USER" "$DOMINO_GROUP" 644
  install_file "$START_SCRIPT_DIR/systemdbs.ind" "$DOMINO_DATA_PATH/systemdbs.ind" "$DOMINO_USER" "$DOMINO_GROUP" 644
  install_file "$START_SCRIPT_DIR/domino.cfg" "/etc/sysconfig/domino.cfg" "$DOMINO_USER" "$DOMINO_GROUP" 644

else
  install_file_noupdate "$DOMINO_INSTALL_CONFIG_FILE" "$DOMINO_INSTALL_CONFIG_TARGET" "$DOMINO_USER" "$DOMINO_GROUP" 644
  install_file_noupdate "$START_SCRIPT_DIR/systemdbs.ind" "$DOMINO_DATA_PATH/systemdbs.ind" "$DOMINO_USER" "$DOMINO_GROUP" 644
  install_file_noupdate "$START_SCRIPT_DIR/domino.cfg" "/etc/sysconfig/domino.cfg" "$DOMINO_USER" "$DOMINO_GROUP" 644
fi

copy_one_touch_templates

# if old start script location exists, replace it with link to new start script location 

OLD_RC_DOMINO_SCRIPT_LOCATION=/opt/ibm/domino/rc_domino_script

if [ -e "$OLD_RC_DOMINO_SCRIPT_LOCATION" ]; then
  rm -f "$OLD_RC_DOMINO_SCRIPT_LOCATION"
  create_link $DOMINO_START_SCRIPT_DIR/rc_domino_script $OLD_RC_DOMINO_SCRIPT_LOCATION
  echo link for legacy start script location created [$OLD_RC_DOMINO_SCRIPT_LOCATION]
fi

# check if running inside a container
if [ -e "/.dockerenv" ]; then
  DOCKER_ENV=yes
fi

# Podman has it's own name
if [ -e "/run/.containerenv" ]; then
  DOCKER_ENV=yes
fi

# K8s environment
if [ -n "$KUBERNETES_SERVICE_HOST" ]; then
  DOCKER_ENV=yes
fi

# set link to include script as 'domino' into path
if [ "$DOCKER_ENV" = "yes" ]; then
  # for Docker we just link the main script
  create_link "$DOMINO_START_SCRIPT_DIR/rc_domino_script" "$DOMINO_SCRIPT_BIN"

else
  # create symbolic link in old standard init.d location if OS has init.d
  if [ -e "$INIT_PATH" ]; then
    if [ ! -e "$INIT_PATH/$DOMINO_RC_NAME" ]; then
      create_link "$DOMINO_SCRIPT_BIN" "$INIT_PATH/$DOMINO_RC_NAME"
    fi
  fi
fi

if [ "$DOCKER_ENV" = "yes" ]; then
  # when running in a Docker environment, don't use systemd/init.d
  echo "Docker Environment detected!"
  
  if [ "$PARAM1" = "upd" ]; then
    install_file "$START_SCRIPT_DIR/$DOMINO_DOCKER_SCRIPT" "/$DOMINO_DOCKER_SCRIPT" $ROOT_USER $ROOT_GROUP 755
  else
    install_file_noupdate "$START_SCRIPT_DIR/$DOMINO_DOCKER_SCRIPT" "/$DOMINO_DOCKER_SCRIPT" $ROOT_USER $ROOT_GROUP 755
  fi

elif [ -n "$(uname -r|grep microsoft)" ]; then
  # WSL does not support systemd
  DebugText "WSL detected"

else

  if [ ${LARCH} = "linux" ]; then
    if [ -e /etc/systemd/system ]; then

      install_file_noupdate $START_SCRIPT_DIR/domino.service /etc/systemd/system/$DOMINO_SYSTEMD_NAME $ROOT_USER $ROOT_GROUP 644
      if [ $? -eq 2 ]; then
        systemctl daemon-reload
      fi
    fi

    patch_install_dir "/etc/systemd/system/$DOMINO_SYSTEMD_NAME"
    patch_user_name "/etc/systemd/system/$DOMINO_SYSTEMD_NAME"

    # add domino service (systemd/init.d)
    $DOMINO_SCRIPT_BIN service add

  fi
fi

if [ -e "$DOMINO_SCRIPT_BIN" ]; then
  patch_install_dir "$DOMINO_SCRIPT_BIN"
  patch_user_name "$DOMINO_SCRIPT_BIN"
fi

header Done

exit 0

